package com.jctrip.hotel.common.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * JSON工具类
 */
@Slf4j
public final class JsonUtil {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static String toString(Object obj) {
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("JSONUtil toString error", e);
        }
        return null;
    }

    public static <T> T toObject(Class<T> clazz, String json) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (Exception e) {
            log.error("JSONUtil toObject error", e);
        }
        return null;
    }

    public static <K, V> Map<K, V> toMap(String json) {
        try {
            return OBJECT_MAPPER.readValue(json, new TypeReference<Map<K, V>>() {});
        } catch (Exception e) {
            log.error("JSONMapper toMap error", e);
        }
        return Collections.emptyMap();
    }

    public static <T> List<T> toList(Class<T> clazz, String json) {
        try {
            JavaType valueType = OBJECT_MAPPER.getTypeFactory().constructCollectionType(ArrayList.class, clazz);
            return OBJECT_MAPPER.readValue(json, valueType);
        } catch (Exception e) {
            log.error("JSONUtil toList error", e);
        }
        return Collections.emptyList();
    }

    public static <T> T convert(Class<T> clazz, Object obj) {
        try {
            return OBJECT_MAPPER.convertValue(obj, clazz);
        } catch (Exception e) {
            log.error("JSONMapper toObject error", e);
        }
        return null;
    }

    static {
        // 空值不参与序列化
        OBJECT_MAPPER.setSerializationInclusion(Include.ALWAYS);
        OBJECT_MAPPER.enable(Feature.ALLOW_UNQUOTED_FIELD_NAMES);
        OBJECT_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        OBJECT_MAPPER.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);
        OBJECT_MAPPER.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }
}
